﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using System.IO;

namespace SeleniumToolkit.Util
{
    public class FileAppenderSpecs : ContextSpecification
    {
        protected string fileName;
        protected FileAppender appender;
        protected List<string> files;

        protected override void Context()
        {
            fileName = Path.GetTempFileName();
            appender = new FileAppender(fileName, "*.js");


            CreateTempFiles();
        }

        protected override void CleanUpContext()
        {
            appender.Dispose();

            if (File.Exists(fileName))
            {
                File.Delete(fileName);
            }
            files.ForEach(file =>
            {
                if (File.Exists(file))
                    File.Delete(file);
            });
        }

        #region helper methods
        private void CreateTempFiles()
        {
            files = new List<string>();

            for (int i = 1; i < 3; i++)
            {
                string file = Path.GetTempFileName();
                File.WriteAllText(file, String.Format("file content for {0}", i));

                files.Add(file);
            }
        }
        #endregion

        [TestFixture]
        public class WhenAppendingFiles : FileAppenderSpecs
        {
            protected override void Because()
            {
                // append a file
                appender.Append(files[0]);
                appender.Append(files[1]);
                appender.Dispose();
            }
            
            [Test]
            public void ShouldCreateAFile()
            {
                File.Exists(fileName).ShouldBeTrue();
            }

            [Test]
            public void ShouldContainFileContent()
            {
                string[] lines = File.ReadAllLines(fileName);
                lines.ShouldContain("file content for 2");
            }

            [Test]
            public void ShouldContainHeaderForEachIncludedFile()
            {
                string[] lines = File.ReadAllLines(fileName);

                lines.ShouldContain(String.Format("// {0}", files[0]));
                lines.ShouldContain(String.Format("// {0}", files[1]));
            }
        }

        [TestFixture]
        public class WhenAppendingInvalidFile : FileAppenderSpecs
        {
            protected Exception ex;

            protected override void Because()
            {
                ex = new MethodThatThrows(() => 
                        {
                            appender.Append("C:\\IllegalFile.js");
                        }).GetException();
            }

            [Test]
            public void ShouldThrowException()
            {
                ex.ShouldNotBeNull();
            }

            [Test]
            public void ShouldContainFileNameInMessage()
            {
                ex.Message.Contains("C:\\IllegalFile.js").ShouldBeTrue();
            }

            [Test]
            public void ShouldBeFileNotFoundException()
            {
                ex.ShouldBeOfType(typeof(FileNotFoundException));
            }
        }

        [TestFixture]
        public class WhenAppendingRelativePathFile : FileAppenderSpecs
        {
            protected Exception ex;

            protected override void Because()
            {
                appender.Append("file-appender-test.js");
                appender.Dispose();
            }

            [Test]
            public void ShouldIncludeFileFromCurrentApplicationFolder()
            {
                string[] lines = File.ReadAllLines(fileName);
                Assert.IsTrue(lines.Length > 2);
            }
        }
    }

    
}
